<?php

namespace app\api\controller;

use addons\jiezicommon\service\Tools;
use app\common\controller\Api;
use think\Config;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 管理接口
 */
class Manage extends Api
{
    protected $noNeedLogin = '*';
    protected $noNeedRight = '*';

    public function _initialize()
    {
        parent::_initialize();

        if($this->request->action() == 'getuserdata'){

        }
        elseif ($this->auth->group_id != config('admin_group_id')) {
            $this->error(__('You have no permission'));
        }
    }


    /**
     * 设置积分价格
     *
     * @ApiMethod (POST)
     * @ApiParams (name="points_price", type="float", required=true, description="价格", default="70")
     * @ApiInternal
     */
    public function setPointsPrice(){
        $this->error('');
        $price = input('points_price/f');
        if($price <= 0){
            $this->error('价格需大于零');
        }
        //获取小数点位置
        $pos = strpos($price, '.');
        if($pos > 0){
            $other = substr($price, $pos + 1);
            if(strlen($other) > 2){
                $this->error('请保留小数点后最多两位数字');
            }
        }
        \app\common\model\Config::where('name', 'points_price')->setField('value', $price);
        \app\common\model\Config::refreshFile(true);
        $this->success('操作成功');
    }


    /**
     * 设置30天购买商城总金额
     *
     * @ApiMethod (POST)
     * @ApiParams (name="total_purchase", type="float", required=true, description="总购买额", default="70")
     * @ApiInternal
     */
    public function setTotalPurchase(){
        $this->error('');

        $total_purchase = input('total_purchase/f');
        if($total_purchase <= 0){
            $this->error('总金额需大于零');
        }

        //获取小数点位置
        $pos = strpos($total_purchase, '.');
        if($pos > 0){
            $other = substr($total_purchase, $pos + 1);
            if(strlen($other) > 2){
                $this->error('请保留小数点后最多两位数字');
            }
        }
        \app\common\model\Config::where('name', 'member_purchase_in_a_cycle')->setField('value', $total_purchase);
        \app\common\model\Config::refreshFile(true);
        $this->success('操作成功');
    }

    /**
     * 获取30天购买商城总金额、积分价格
     *
     * @ApiMethod (POST)
     * @ApiInternal

     */
    public function getConfig(){
        $return_data = [
            'total_purchase' => config('site.member_purchase_in_a_cycle'),
            'points_price' => config('site.points_price'),
            'recharge_cargo_value_to_points_rate' => (float)config('recharge_cargo_value_to_points_rate'),
        ];
        $this->success('获取成功', $return_data);
    }

    /**
     * 充值货值
     *
     * @ApiMethod (POST)
     * @ApiParams (name="receive_id", type="int", required=true, description="接收人ID", default="1")
     * @ApiParams (name="money", type="float", required=true, description="货值金额", default="10")
     * @ApiInternal

     */
    public function rechargeCargoValue(){
        $this->error('');

        $receive_id = input('receive_id/d');
        if($receive_id <= 0){
            $this->error('请输入接收人ID');
        }
        $receive = \app\common\model\User::get($receive_id);
        if(empty($receive)){
            $this->error('接收人错误');
        }
        if($receive['status'] != 'normal'){
            $this->error('接收人状态异常');
        }
        $money = input('money/f');
        if($money <= 0.01){
            $this->error('请输入充值金额');
        }
        //获取小数点位置
        $pos = strpos($money, '.');
        if($pos > 0){
            $other = substr($money, $pos + 1);
            if(strlen($other) > 2){
                $this->error('请保留小数点后最多两位数字');
            }
        }
        $rate = (float)config('recharge_cargo_value_to_points_rate');
        if($rate <= 0){
            $this->error('充值比率错误');
        }
        //当日积分价格
        $points_price = (float)config('site.points_price');
        if($points_price <= 0){
            $this->error('当日积分价格错误');
        }
        //需减少的平台积分
        $need_system_points = bcdiv($money, $rate, 6);
        $need_system_points = bcdiv($need_system_points,$points_price, 6);
        //平台积分
        $system_points = \app\common\model\SystemData::getVal('points');
        if($need_system_points > $system_points){
            $this->error('平台积分不足');
        }
        Db::startTrans();
        try{
            $sn = Tools::getOrderSn();
            //增加用户货值
            \app\common\model\User::cargo_value(1,$sn, 0, $money,$receive_id, '平台充值',$this->auth->id);
            //减少平台积分
            \app\common\model\SystemData::points(2, $sn, -$need_system_points, '充值减积分', $this->auth->id);
            //todo 返给上级货值
            //获取上级路径
            $user_list = \addons\jiezicommon\service\Tools::getInstance()->getUserParentPath($receive_id);
//货值来源
//1：货值由平台给客户充值得来，平台充值时消耗初始积分，货值数量÷10÷当日积分价格
//得使用得积分
//2：由系统自动奖励得来
//系统奖励机制分两级（假设一星为高级）
//一星用户下的二星用户推荐一个普通用户成交10000货值，一星客户得系统奖励总货值
//10%货值奖励，二星客户得系统奖励总货值20%货值奖励
//一星客户的直推客户成交10000，一星客户得货值30%的货值奖励。
//二星客户直推得系统奖励总货值20%货值奖励

            //二星是否获得奖励
            $star_2 = false;
            $star_2_val = 0;
            $star_2_user_id = 0;
            //一星是否获得奖励
            $star_1 = false;
            $star_1_val = 0;
            $star_1_user_id = 0;
            foreach($user_list as $p){
                //排除自己
                if($p['id'] == $receive_id){
                    continue;
                }
                //当前是普通身份，推荐者是二星
                if($receive['group_id'] == 1 && $receive['group_id'] + 2 == $p['group_id']){
                    //是否直推
                    if($receive['parent_id'] == $p['id']){
                        $star_2_val = bcmul($money, 0.2, 6);
                    }else{
                        $star_2_val = bcmul($money, 0.2, 6);
                    }
                    $star_2_user_id = $p['id'];
                    $star_2 = true;
                }
                //当前是普通身份，推荐者是一星
                if($receive['group_id'] == 1 && $receive['group_id'] + 1 == $p['group_id']){
                    //是否直推
                    if($receive['parent_id'] == $p['id']){
                        $star_1_val = bcmul($money, 0.3, 6);
                    }else{
                        $star_1_val = bcmul($money, 0.1, 6);
                    }
                    $star_1_user_id = $p['id'];
                    $star_1 = true;
                }
                //当前是一星身份，推荐者是二星
                if($receive['group_id'] == 2 && $receive['group_id'] + 1 == $p['group_id']){
                    //是否直推
                    if($receive['parent_id'] == $p['id']){
                        $star_1_val = bcmul($money, 0.3, 6);
                    }else{
                        $star_1_val = bcmul($money, 0.1, 6);
                    }
                    $star_1_user_id = $p['id'];
                    $star_1 = true;
                }
            }
//            var_dump($star_2_user_id, $star_1_user_id);die;
            //二星奖励
            $star_2_user_id > 0 && \app\common\model\User::cargo_value(3, $sn, 0, $star_2_val, $star_2_user_id, '奖励', $this->auth->id);
            //一星奖励
            $star_1_user_id > 0 && \app\common\model\User::cargo_value(3, $sn, 0, $star_1_val, $star_1_user_id, '奖励', $this->auth->id);
//            var_dump($user_list);die;
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('操作成功');
    }

    /**
     * 货值扣减
     *
     * @ApiMethod (POST)
     * @ApiParams (name="receive_id", type="int", required=true, description="扣减人ID", default="1")
     * @ApiParams (name="receive_nickname", type="string", required=true, description="扣减人昵称", default="")
     * @ApiParams (name="receive_tel", type="string", required=true, description="扣减人电话", default="")
     * @ApiParams (name="money", type="float", required=true, description="货值数量", default="10")
     * @ApiInternal

     */
    public function minusCargoValue(){
        $receive_id = input('receive_id/d');
        $receive_nickname = xss_clean(input('receive_nickname'));
        $receive_tel = input('receive_tel/d');
        if($receive_id <= 0 && !$receive_nickname){
            $this->error('请输入扣减人ID');
        }
        if($receive_id > 0) {
            $receive = \app\common\model\User::get($receive_id);
        }else{
            $receive = \app\common\model\User::get(['username' => $receive_nickname]);
        }
        if(empty($receive)){
            $this->error('扣减人错误');
        }
        if($receive['status'] != 'normal'){
            $this->error('扣减人状态异常');
        }

        if($receive_tel && $receive['mobile']) {
            if ($receive['mobile'] != $receive_tel){
                $this->error('扣减人电话错误');
            }
        }

        $cargo_value = $receive['cargo_value'];
        if($cargo_value < 0){
            $this->error('扣减人货值异常');
        }
        $money = input('money/f');
        if($money <= 0.01){
            $this->error('请输入扣减货值数量');
        }
        //获取小数点位置
        $pos = strpos($money, '.');
        if($pos > 0){
            $other = substr($money, $pos + 1);
            if(strlen($other) > 2){
                $this->error('请保留小数点后最多两位数字');
            }
        }
        if($money > $cargo_value){
            $this->error('扣减数量不能超过用户拥有数量');
        }
//        $points = $receive['points'];
//        if($points < 0){
//            $this->error('扣减人积分异常');
//        }
//        $activity_points = $receive['activity_points'];
//        if($activity_points < 0){
//            $this->error('扣减人活动积分异常');
//        }

        Db::startTrans();
        try{
            $sn = Tools::getOrderSn();
            //减少用户货值
            $cargo_value > 0 && \app\common\model\User::cargo_value(2, $sn, 0, -$money, $receive_id, '扣减', $this->auth->id);

            //减少用户积分
//            $points > 0 && \app\common\model\User::points(2, $sn, 0, -$points, $receive_id, '扣减', $this->auth->id);

            //减少用户活动积分
//            $activity_points > 0 && \app\common\model\User::activity_points(2, $sn, -$activity_points, $receive_id, '扣减', $this->auth->id);

            //增加平台货值
            $cargo_value > 0 && \app\common\model\SystemData::cargo_value(1, $sn, $money, '扣减自增', $this->auth->id);

            //增加平台积分
//            $points > 0 && \app\common\model\SystemData::points(3, $sn, $points, '扣减自增', $this->auth->id);

            //增加平台活动积分
//            $activity_points > 0 && \app\common\model\SystemData::activity_points(1, $sn, $activity_points, $activity_points, '扣减自增', $this->auth->id);
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('操作成功');
    }

    /**
     * 充值积分
     *
     * @ApiMethod (POST)
     * @ApiParams (name="receive_id", type="int", required=true, description="接收人ID", default="1")
     * @ApiParams (name="money", type="float", required=true, description="货值金额", default="10")
     */
    public function rechargePoints(){
        $receive_id = input('receive_id/d');
        if($receive_id <= 0){
            $this->error('请输入接收人ID');
        }
        $receive = \app\common\model\User::get($receive_id);
        if(empty($receive)){
            $this->error('接收人错误');
        }
        if($receive['status'] != 'normal'){
            $this->error('接收人状态异常');
        }
        $money = input('money/f');
        if($money <= 0.01){
            $this->error('请输入充值金额');
        }
        //获取小数点位置
        $pos = strpos($money, '.');
        if($pos > 0){
            $other = substr($money, $pos + 1);
            if(strlen($other) > 2){
                $this->error('请保留小数点后最多两位数字');
            }
        }
        Db::startTrans();
        try{
            $sn = Tools::getOrderSn();
            //增加用户积分
            \app\common\model\User::points(1,$sn, 0, $money,$receive_id, '平台充值',$this->auth->id);
            
            //是否已经给予父级宝豆parent_speed_order_id
            $user = \app\common\model\User::where('id', $receive_id)->find();
            
            if($user['parent_id']){
                //父级宝豆=充值积分的百分比
                $cargo_value = $money * 0.1;
                $cargo_value > 0 && \app\common\model\User::cargo_value(2, $sn, 0, $cargo_value, $user['parent_id'], '充值', $this->auth->id);                
            }
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('操作成功');
    }

    /**
     * 积分扣减
     *
     * @ApiMethod (POST)
     * @ApiParams (name="receive_id", type="int", required=true, description="扣减人ID", default="1")
     * @ApiParams (name="receive_nickname", type="string", required=true, description="扣减人昵称", default="")
     * @ApiParams (name="receive_tel", type="string", required=true, description="扣减人电话", default="")
     * @ApiParams (name="money", type="float", required=true, description="货值数量", default="10")
     */
    public function minusPoints(){
        $this->error('');
        $receive_id = input('receive_id/d');
        $receive_nickname = xss_clean(input('receive_nickname'));
        $receive_tel = input('receive_tel/d');
        if($receive_id <= 0 && !$receive_nickname){
            $this->error('请输入扣减人ID');
        }
        if($receive_id > 0) {
            $receive = \app\common\model\User::get($receive_id);
        }else{
            $receive = \app\common\model\User::get(['username' => $receive_nickname]);
        }
        if(empty($receive)){
            $this->error('扣减人错误');
        }
        if($receive['status'] != 'normal'){
            $this->error('扣减人状态异常');
        }

        if($receive_tel && $receive['mobile']) {
            if ($receive['mobile'] != $receive_tel){
                $this->error('扣减人电话错误');
            }
        }

        $points = $receive['points'];
        if($points < 0){
            $this->error('扣减人积分异常');
        }
        $money = input('money/f');
        if($money <= 0.01){
            $this->error('请输入扣减积分数量');
        }
        //获取小数点位置
        $pos = strpos($money, '.');
        if($pos > 0){
            $other = substr($money, $pos + 1);
            if(strlen($other) > 2){
                $this->error('请保留小数点后最多两位数字');
            }
        }
        if($money > $points){
            $this->error('扣减数量不能超过用户拥有数量');
        }
//        $points = $receive['points'];
//        if($points < 0){
//            $this->error('扣减人积分异常');
//        }
//        $activity_points = $receive['activity_points'];
//        if($activity_points < 0){
//            $this->error('扣减人活动积分异常');
//        }
        Db::startTrans();
        try{
            $sn = Tools::getOrderSn();
            //减少用户积分
            $points > 0 && \app\common\model\User::points(2, $sn, 0, -$money, $receive_id, '扣减', $this->auth->id);
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('操作成功');
    }

    

    /**
     * 积分扣减
     *
     * @ApiMethod (POST)
     * @ApiParams (name="receive_id", type="int", required=true, description="扣减人ID", default="1")
     * @ApiParams (name="receive_nickname", type="string", required=true, description="扣减人昵称", default="")
     * @ApiParams (name="receive_tel", type="string", required=true, description="扣减人电话", default="")
     * @ApiParams (name="money", type="float", required=true, description="货值数量", default="10")
     */
    public function minusActivityPoints(){
        $this->error('');
        $receive_id = input('receive_id/d');
        $receive_nickname = xss_clean(input('receive_nickname'));
        $receive_tel = input('receive_tel/d');
        if($receive_id <= 0 && !$receive_nickname){
            $this->error('请输入扣减人ID');
        }
        if($receive_id > 0) {
            $receive = \app\common\model\User::get($receive_id);
        }else{
            $receive = \app\common\model\User::get(['username' => $receive_nickname]);
        }
        if(empty($receive)){
            $this->error('扣减人错误');
        }
        if($receive['status'] != 'normal'){
            $this->error('扣减人状态异常');
        }

        if($receive_tel && $receive['mobile']) {
            if ($receive['mobile'] != $receive_tel){
                $this->error('扣减人电话错误');
            }
        }

        $points = $receive['activity_points'];
        if($points < 0){
            $this->error('扣减人积分异常');
        }
        $money = input('money/f');
        if($money <= 0.01){
            $this->error('请输入扣减积分数量');
        }
        //获取小数点位置
        $pos = strpos($money, '.');
        if($pos > 0){
            $other = substr($money, $pos + 1);
            if(strlen($other) > 2){
                $this->error('请保留小数点后最多两位数字');
            }
        }
        if($money > $points){
            $this->error('扣减数量不能超过用户拥有数量');
        }
//        $points = $receive['points'];
//        if($points < 0){
//            $this->error('扣减人积分异常');
//        }
//        $activity_points = $receive['activity_points'];
//        if($activity_points < 0){
//            $this->error('扣减人活动积分异常');
//        }
        Db::startTrans();
        try{
            $sn = Tools::getOrderSn();
            //减少用户积分
            $points > 0 && \app\common\model\User::activity_points(2, $sn, -$money, $receive_id, '扣减', $this->auth->id);
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('操作成功');
    }

    /**
     * 获取用户数据
     *
     * @ApiMethod (POST)
     * @ApiParams (name="receive_id", type="int", required=true, description="扣减人ID", default="1")
     * @ApiParams (name="receive_nickname", type="string", required=true, description="扣减人昵称", default="")
     * @ApiParams (name="receive_tel", type="string", required=true, description="扣减人电话", default="")
     */
    public function getUserData(){
        $receive_id = input('receive_id/d');
        $receive_nickname = xss_clean(input('receive_nickname'));
        if($receive_id <= 0 && !$receive_nickname){
            $this->error('请输入扣减人ID');
        }
        if($receive_id > 0) {
            $receive = \app\common\model\User::get($receive_id);
        }else{
            $receive = \app\common\model\User::get(['username' => $receive_nickname]);
        }
        if(empty($receive)){
            $this->error('扣减人错误');
        }
        if($receive['status'] != 'normal'){
            $this->error('扣减人状态异常');
        }

        // $cargo_value = $receive['cargo_value'];
        // if($cargo_value < 0){
        //     $this->error('扣减人货值异常');
        // }
        // $points = $receive['points'];
        // if($points < 0){
        //     $this->error('扣减人积分异常');
        // }
        // $activity_points = $receive['activity_points'];
        // if($activity_points < 0){
        //     $this->error('扣减人活动积分异常');
        // }
        $return_data = [
            'username' => $receive['username'],
            'cargo_value' => fixNum($receive['cargo_value']),
            'points' => fixNum($receive['points']),
            'activity_points' => fixNum($receive['activity_points']),
        ];
        $this->success('操作成功', $return_data);
    }

    /**
     * 获取平台积分记录
     *
     * @ApiMethod (POST)
     * @ApiParams (name="type", type="int", required=false, sample="0", description="类型:0:全部,1:收入,2:转出,3:自提", default="0")
     * @ApiParams (name="page", type="int", required=false, sample="1", description="页码,默认=1", default="1")
     * @ApiParams (name="limit", type="int", required=false, sample="10", description="每页条数,默认=10", default="10")
     * @ApiInternal
     */
    public function getPointsList(){
        $this->error();

        $params = input();
        $page = empty($params['page']) ? 1 : intval($params['page']);
        $limit = empty($params['limit']) ? 10 : intval($params['limit']);
        $type = empty($params['type']) ? 0 : intval($params['type']);
        if($type < 0 || $type > 3){
            $type = 0;
        }
        $return_data = [
            'list' => []
        ];
        $table = \app\common\model\SystemActivityPointsLog::alias('t');
        if($type){
            $table->whereIn('t.type', $type);
        }
        \think\Lang::load(APP_PATH . 'admin/lang/zh-cn/system_activity_points_log.php');
        $fields = 'id,type,sn,money,num,createtime';
        $res = $table->field($fields)->order('id desc')
            ->paginate($limit, false, ['page' => $page])
            ->each(function($item){
                $item['money'] = fixNum($item['money']);
                $item['num'] = fixNum($item['num']);
                $item['createtime_str'] = date('Y-m-d H:i', $item['createtime']);
            });
        $sql = $table->getLastSql();
        $list = $res->items();
        $return_data['list'] = $list;
        $return_data['total'] = $res->total();
        $return_data['sql'] = $sql;
        $this->success('返回成功', $return_data);
    }

    /**
     * 释放积分
     *
     * @ApiMethod (POST)
     * @ApiParams (name="money", type="int", required=true, description="释放数量", default="1")
     */
    public function release_points(){
        $money = input('money/d');
        if($money <= 0){
            $this->error('请输入释放数量');
        }
        $model = new \app\common\model\ReleasePointLog();
        //获取用户总积分和总加速值
        $total = \app\common\model\User::where('status', 'normal')->where('points','gt',0)->where('cargo_value','egt',0)->field('sum(points) as points,sum(cargo_value) as speed')->find();
        $total_points = $total['points'] ?? 0;
        $total_speed = $total['speed'] ?? 0;
        if($total_points < $money){
            $this->error('释放数量不能大于用户总积分');
        }
        Db::startTrans();
        try {
            //用户最大可用加速值=用户积分*config('site.transfer_to_lvse_point_percent')
            $percent = config('site.transfer_to_lvse_point_percent') / 100;
            //修正完的加速值总数
            $total_speed = 0;

            //修正完加速值的用户数据
            $user_list = [];
            //获取积分大于0的用户
            \app\common\model\User::where('status', 'normal')->where('points','gt',0)->where('cargo_value','egt',0)->chunk(100, function($users) use(&$user_list, $percent, &$total_speed){

                foreach ($users as $user) {
                    $point_plus = $user['points'] * $percent;
                    $max_speed = $point_plus > $user['cargo_value'] ? $user['cargo_value'] : $point_plus;
                    $total_speed += $max_speed;
                    $user_list[$user['id']] = [
                        'points' => $user['points'],
                        'point_plus' => $point_plus,
                        'cargo_value' => $user['cargo_value'],
                        'max_speed' => $max_speed,
                    ];
                }
            });

            $fee = 0;
            $total_points_speed = $total_points + $total_speed;
            if($total_points_speed <= 0){
                Db::rollback();
                $this->error('总积分和总加速值不能小于等于0');
            }
            $sn = $model::create(['points' => $money, 'total_points' => $total_points, 'total_speed' => $total_speed, 'memo' => '释放', 'createtime' => time()])->getLastInsId();

            //更新用户积分和加速值
            foreach($user_list as $user_id => $user){
                $points = $money * ($user['points'] + $user['max_speed']) / $total_points_speed;
                if($points <= 0){
                    Db::rollback();
                    $this->error('用户获得绿色积分不能小于等于0');
                }
                // echo 'percent:' . (($user['points'] + $user['max_speed']) / $total_points_speed) . PHP_EOL;
                // echo 'points:' . $user['points'] . PHP_EOL;
                // echo 'point_plus:' . $user['point_plus'] . PHP_EOL;
                // echo 'cargo_value:' . $user['cargo_value'] . PHP_EOL;
                // echo 'max_speed:' . $user['max_speed'] . PHP_EOL;
                // echo 'new_points:' . $points . PHP_EOL;
                \think\Log::info('user_points:' . $user['points']);
                \think\Log::info('percent:' . $percent);
                \think\Log::info('cargo_value:' . $user['cargo_value']);
                \think\Log::info('max_speed:' . $user['max_speed']);
                \think\Log::info('new_points:' . $points);
                if($user['points'] < $points){
                    \think\Log::error('user_points:' . $user['points']);
                    \think\Log::error('new_points:' . $points);
                }
                \think\Log::info('another==================');

                //增加用户的绿色积分
                \app\common\model\User::activity_points(1, $sn, $points, $user_id, '转化');
                //减少用户的积分                
                \app\common\model\User::points(2, $sn, $fee, -$points, $user_id, '转化');
            }
            // echo 'total_points_speed:' . $total_points_speed . PHP_EOL;

            // var_dump($user_list);die;
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('释放成功');
    }

    /**
     * 释放积分日志
     *
     * @ApiMethod (POST)
     * @ApiParams (name="page", type="int", required=true, description="当前页", default="1")
     * @ApiParams (name="limit", type="int", required=true, description="每页数量", default="10")
     */
    public function release_points_log(){
        $page = input('page/d', 1);
        $limit = input('limit/d', 10);
        $model = new \app\common\model\ReleasePointLog();
        $res = $model->order('id','desc')->paginate($limit);
        $list = $res->items();
        foreach($list as $key => $val){
            $list[$key]['createtime'] = date('Y-m-d H:i:s', $val['createtime']);
        }
        $return_data['list'] = $list;
        $return_data['total'] = $res->total();
        $this->success('返回成功', $return_data);
    }
}